package pl.rzarajczyk.breaktime;

import javax.annotation.PostConstruct;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import pl.rzarajczyk.breaktime.gui.BreakWindow;
import pl.rzarajczyk.breaktime.gui.TimerWindow;
import pl.rzarajczyk.breaktime.utils.Scheduler;
import pl.rzarajczyk.breaktime.utils.SchedulerEvent;
import pl.rzarajczyk.breaktime.utils.SettingsEvent;

/**
 *
 * @author rafalz
 */
public class Break {
    private BreakSchedulerEvent breakSchedulerEvent;
    private BreakSettingsEvent breakSettingsEvent;

    @Autowired
    private BreakWindow breakWindow;
    
    @Autowired
    private TimerWindow timerWindow;
    
    @Autowired
    private BreakTimeSettings settings;
    
    @Autowired
    private Scheduler scheduler;
    
    private int timeToFinish;
    private boolean inProgress;
    
    private Log log = LogFactory.getLog(getClass());

    public Break() {
        breakSettingsEvent = new BreakSettingsEvent();
        breakSchedulerEvent = new BreakSchedulerEvent();
    }
    
    @PostConstruct
    public void open() {
        onFinish();
        scheduler.schedule(breakSchedulerEvent);
        settings.addEvent(breakSettingsEvent);
    }
    
    private void onUpdate() {
        log.info("Settings update");
        if ( inProgress ) {
            onStart();
        } else {
            onFinish();
        }
    }
    
    private void onStart() {
        log.info("Break start");
        timeToFinish = settings.getMicroBreakDuration();
        timerWindow.setMicroBreakInProgress(true);
        breakWindow.start(timeToFinish);
        inProgress = true;        
    }
    
    private void onFinish() {
        log.info("Break finish");
        timeToFinish = settings.getMicroBreakInterval();
        timerWindow.setMicroBreakInProgress(false);
        breakWindow.stop();
        inProgress = false;
    }
    
    private void onTick() {
        timeToFinish -= Scheduler.TIME_UNIT;
        timerWindow.tick(timeToFinish);
        if ( inProgress ) {
            breakWindow.tick(timeToFinish);
        }
    }

    @Override
    public String toString() {
        return "BreakTime break object";
    }
    
    // =========================================================================
    
    class BreakSchedulerEvent implements SchedulerEvent {

        @Override
        public void onTick() {
            Break.this.onTick();
        }

        @Override
        public void onStart() {
            Break.this.onStart();
        }

        @Override
        public void onFinish() {
            Break.this.onFinish();
        }

        @Override
        public int duration() {
            return settings.getMicroBreakDuration();
        }

        @Override
        public int interval() {
            return settings.getMicroBreakInterval();
        }
        
    }
    
    class BreakSettingsEvent implements SettingsEvent {

        @Override
        public void onAfterLoad() {
            // nothing
        }

        @Override
        public void onBeforeSave() {
            // nothing
        }

        @Override
        public void onUpdate() {
            Break.this.onUpdate();
        }
        
    }
    
}
